package com.boilermaker.lotterysystem.dao.handler;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import com.boilermaker.lotterysystem.dao.dataobject.Encrypt;
import org.apache.ibatis.type.*;

import java.nio.charset.StandardCharsets;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


@MappedTypes(Encrypt.class) // Java 对象类型
@MappedJdbcTypes(JdbcType.VARCHAR) // 数据库支持的类型（JDBC 所能识别的类型）
public class EncryptHandler extends BaseTypeHandler<Encrypt> {

    // 使用固定密钥（若随机生成，应用重启后会产生新的密钥，旧数据将无法使用新密钥解密）
    private final byte[] KEY = "123456789abcdefg".getBytes(StandardCharsets.UTF_8);


    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Encrypt parameter, JdbcType jdbcType) throws SQLException {
        // 入参前完成加密
        AES aes = SecureUtil.aes(KEY);
        String encryptedData = aes.encryptHex(parameter.getValue());

        ps.setString(i, encryptedData);
    }

    @Override
    public Encrypt getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return getDecryptedData(rs.getString(columnName));
    }

    @Override
    public Encrypt getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return getDecryptedData(rs.getString(columnIndex));
    }

    @Override
    public Encrypt getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return getDecryptedData(cs.getString(columnIndex));
    }

    /**
     * 出参前调用此方法完成解密
     *
     * @param encryptedData
     * @return
     */
    private Encrypt getDecryptedData(String encryptedData) {
        return new Encrypt(SecureUtil.aes(KEY).decryptStr(encryptedData));
    }
}
